const { env, http_options } = require('config')

/**
 * 闭包方式获取 http 请求方法, 外部支持传入app对象, 
 * 在 app.js 中挂载必须将 this 传入;
 * 
 * 解决启动时挂载app.http, app对象还未构造完成导致 app.isLogin() 的 undefined 问题;
 * 解决方案：
 *  1. 使用闭包，支持在 app.js 中传入 this 对象
 *  2. 不用闭包，用 new 改变this指向。
 * @param {Object} app = getApp()
 */
function http(app) {
  app = app || getApp()
  if (!app) {
    wx.showToast({  icon: 'none', title: 'http 模块初始化失败,参数app不存在' })
    return null
  }

  /**
   * 调用 wx.cloud.callFunction 请求云函数
   * @param {String} name 云函数文件名
   * @param {Object} data 请求数据 {action: 'action name', ...data}
   * @param {Object} options 配置参数; 详情见 http_options
   */
  return function(name, data, options = {}) {
    options = Object.assign({}, http_options, options)
    return new Promise((resolve, reject) => {
      // 登录检查
      if (options.login && !app.isLogin()) {
        return wx.showModal({
          title: options.loginTitle,
          content: options.loginText,
          success: res => {
            res.confirm && wx.switchTab({
              url: options.loginPage
            })
          }
        })
      }
      // 加载动画
      options.loading && wx.showLoading({
        title: options.loading
      })
      // 发起请求
      wx.cloud.callFunction({
        name, data,
        success: res => resolve(res.result),
        fail: err => {
          var debug = app.global.user && app.global.user.role === 'admin' || env === 'dev'
          wx.showToast({
            icon: 'none',
            title: debug ? `[云函数][${name}${data.action ? '.' + data.action : ''}]调用失败` : '请求失败'
          })
          reject(err)
        },
        complete: () => {
          options.loading && wx.hideLoading()
        }
      })
    })
  }
}

module.exports = {
  http
}
